package com.dev.op.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dev.op.VO.ProblemPostVO;
import com.dev.op.VO.ResultVO;
import com.dev.op.entity.Problem;
import com.dev.op.entity.User;
import com.dev.op.enums.ResultCode;
import com.dev.op.exceptions.BizException;
import com.dev.op.service.ProblemService;
import com.dev.op.service.RedisService;
import com.dev.op.util.RedisUtil;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
import java.util.StringTokenizer;

@PreAuthorize("hasAnyRole('admin','teacher','student')")
@RestController
@RequestMapping("/problems")
public class ProblemController {

    @Autowired
    ProblemService problemService;

    @Autowired
    RedisService redisService;

    @Autowired
    RBloomFilter<String> problemIdBloomFilter;

    //应用布隆过滤器
    @GetMapping("/{id}")
    public ResultVO<Problem> getProblemById(@PathVariable int id) {
        //无效id 过滤
        return problemService.getProblemById(id);
    }

    //DEBUG
    @GetMapping("/w")
    public Object whoami(Authentication auth) {
        return auth.getAuthorities(); // 打印当前拥有的权限列表
    }

    //任何 与problem有关的的 增删改后，需要 全 更新这个
    //

    @GetMapping("")
    public ResultVO<Page<Problem>> getAllProblem(@RequestParam("page") String page,@RequestParam("size") String size) {
        try {
            //先尝试向redis中查找
            Page<Problem> pagedProblems = redisService.getProblemsInPage(Integer.parseInt(page), Integer.parseInt(size));
            if (pagedProblems != null) {
                //System.out.println("从redis获取");
                return ResultVO.success(pagedProblems);
            }
            //查询数据库并保存
            else {
                //System.out.println("从数据库查询获取");
                Page<Problem> pageResult = problemService.listProblems(
                        Integer.parseInt(page), Integer.parseInt(size));
                //保存到redis中
                redisService.saveProblemsInPageSize(pageResult, 36000);
                return ResultVO.success(pageResult);
            }
        }
        catch (Exception e) {
            return ResultVO.error(ResultCode.PARAM_ERROR.message());
        }
    }

    //要触发redis更新: 删除最后一页的缓存
    @PreAuthorize("hasRole('admin')")
    @PostMapping
    public ResultVO<?> addProblem(@RequestBody ProblemPostVO problemPostVO) {
        //System.out.println(problemPostVO);
        //删除最后一个分页的缓存
        redisService.deleteLastPageOfProblemCache();
        problemService.saveWithTestCases(problemPostVO);
        return ResultVO.success(null);
    }

    //会触发两个缓存更新，需要被优化
    @PreAuthorize("hasRole('admin')")
    @PutMapping
    public ResultVO<Problem> updateProblem(@RequestBody Problem problem) {
            //将所有的 分页问题 缓存删除
            redisService.deleteAllPageOfProblemCache();
            //保存问题到redis中
            redisService.saveProblem(problem,36000);
            boolean res = problemService.updateById(problem);
            if (!res) {
                return ResultVO.error(ResultCode.PARAM_ERROR.code(), "update failed");
            } else {
                return ResultVO.success(problem);
            }
    }

    //触发两个个缓存更新，需要被优化
    @PreAuthorize("hasRole('admin')")
    @DeleteMapping("/{id}")
    public ResultVO<Boolean> deleteProblem(@PathVariable int id) {
        try {
            redisService.deleteAllPageOfProblemCache();
            redisService.deleteProblem(String.valueOf(id));
            boolean res = problemService.removeById(id);
            if (!res) {
                return ResultVO.error(ResultCode.PARAM_ERROR.code(), "delete failed");
            } else {
                return ResultVO.success(true);
            }
        }
        catch (Exception e) {
            throw new BizException(ResultCode.FORBIDDEN);
        }
    }
}
